#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <sstream>
#include <map>
#include <iterator>
#include <set>
#include <array>
#include <bitset>

/*
 题目

描述:

请解析IP地址和对应的掩码，进行分类识别。要求按照A/B/C/D/E类地址归类，不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类

A类地址1.0.0.0~126.255.255.255; 

B类地址128.0.0.0~191.255.255.255; 

 C类地址192.0.0.0~223.255.255.255;

 D类地址224.0.0.0~239.255.255.255；

 E类地址240.0.0.0~255.255.255.255

 私网IP范围是：

 10.0.0.0～10.255.255.255

172.16.0.0～172.31.255.255

 192.168.0.0～192.168.255.255

 子网掩码为前面是连续的1，然后全是0
题目类别:

字符串  
难度:

    中级  
运行时间限制:

    10Sec 
内存限制:

    128MByte 
阶段:

入职前练习  
输入:

多行字符串。每行一个IP地址和掩码，已~隔开。如：

10.70.44.68~255.254.255.0

1.0.0.1~255.0.0.0

192.168.0.2~255.255.255.0

19..0.~255.255.255.0
输出:

统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数，之间以空格隔开，根据上面的IP，可以得到：

1.0.0.1~255.0.0.0 ----A类

192.168.0.2~255.255.255.0  ----C类，私有

10.70.44.68~255.254.255.0----错误的掩码

19..0.~255.255.255.0-----错误的IP

可以得到统计数据如下：

1 0 1 0 0 2 1
样例输入:

10.70.44.68~255.254.255.0
1.0.0.1~255.0.0.0
192.168.0.2~255.255.255.0
19..0.~255.255.255.0
样例输出:

1 0 1 0 0 2 1
 */


std::map<std::string, int> m_map;

void init()
{
    std::array<std::string, 7> arr = {"A","B","C","D","E","ERROR","PRIVATE"};
    for(std::array<std::string,7>::iterator it = arr.begin(); it != arr.end(); ++it){
        m_map.insert(std::map<std::string,int>::value_type(*it,0));// = 0;
    }
}

std::vector<std::string> split(const std::string & str, const std::string & sperator)
{
    std::vector<std::string> rst;
    int pos1 = 0;
    int pos2 = str.find(sperator);
    while(std::string::npos != pos2){
        rst.emplace_back(str.substr(pos1, pos2-pos1));
        pos1 = pos2 + sperator.size();
        pos2 = str.find(sperator, pos1);
    }
    if(str.length() > pos1){
        rst.emplace_back(str.substr(pos1));
    }
    return rst;
}

int parseInt(std::string & str)
{
    std::stringstream ss;
    ss<<str;
    int rst = -1;
    ss>>rst;
    return rst;
}

void valid(const std::string & str, std::vector<int> & ip)
{
    std::vector<std::string> secs;
    secs = split(str,".");
    ip.clear();
    for(std::vector<std::string>::iterator it = secs.begin(); it != secs.end(); ++it){
        int tmp = parseInt(*it);
        if(!(tmp < 0 || tmp > 255)){
            if(-1 != tmp){
                ip.emplace_back(tmp);
            }
        }
    }
}

bool ipValidCheck(std::vector<int> & ip)
{
    if(ip.size() != 4){
        m_map.at("ERROR")++;
        return false;
    }
    if(ip.at(0) >=1 && ip.at(0) <= 126){
        m_map.at("A")++;
    }else if(ip.at(0) >=128 && ip.at(0) <= 191){
        m_map.at("B")++;
    }else if(ip.at(0) >=192 && ip.at(0) <= 223){
        m_map.at("C")++;
    }else if(ip.at(0) >=224 && ip.at(0) <= 239){
        m_map.at("D")++;
    }else if(ip.at(0) >=240 && ip.at(0) <= 255){
        m_map.at("E")++;
    }else{
    }
    if(10 == ip.at(0)
       || (172 == ip.at(0) && ip.at(1) >=16 && ip.at(1) <=31)
       || (192 == ip.at(0) && 168 == ip.at(1))){
        m_map.at("PRIVATE")++;
    }
}

bool maskValidCheck(std::vector<int> & msk)
{
    if(msk.size() != 4){
        m_map.at("ERROR")++;
        return false;
    }
    std::string tmp = "";
    for(std::vector<int>::iterator it = msk.begin(); it != msk.end(); ++it){
        tmp += std::bitset<8>((*it)).to_string();
    }
    int pos = tmp.find('0');
    if(std::string::npos != (tmp.substr(pos)).find('1')){
        m_map.at("ERROR")++;
        return false;
    }
    return true;
}

int main()
{
    init();
    std::string tmp;
    int i = 4;
    while(i != 0){
        getline(std::cin, tmp);
        std::vector<std::string> pairs = split(tmp, "~");
        std::vector<int> ip, mask;
        valid(pairs.at(0), ip);
        valid(pairs.at(1), mask);
        if(maskValidCheck(mask)){
            if(ipValidCheck(ip)){

            }
        }
        --i;
    }
    std::cout<<m_map.at("A")<<" "
             <<m_map.at("B")<<" "
             <<m_map.at("C")<<" "
             <<m_map.at("D")<<" "
             <<m_map.at("E")<<" "
             <<m_map.at("ERROR")<<" "
             <<m_map.at("PRIVATE")<<" "<<std::endl;
    return 0;
}